<template>
  <!--  所有数据在tHead和tBody自定义-->
  <div id="main-table">
    <Dialog :center="true" ref="dialog" :form-title="dialogTitle" :determine-button-name="determineButtonName" @determine="determine">
      <!--        插槽自定义表单-->
      <template v-slot:content>
        <el-form v-model="form">
          <el-form-item
            v-for="item in tHead"
            :label="item.label"
            :label-width="formLabelWidth">
            <el-input
              v-model="form[item.prop]"
              autocomplete="off"
              style="width: 180px"></el-input>
          </el-form-item>
        </el-form>
      </template>
    </Dialog>
    <Dialog :form-title="'确认删除'" ref="deleteConfirm" @determine="rowDeleted">

    </Dialog>
    <Table
      :tHead="tHead"
      :tBody="bookDisplay"
      ref="table"
      @rowDelete="rowDelete"
      @rowUpdate="rowUpdate">
      <template v-slot:table-operating v-if="!isAdmin">
        <el-table-column label="加入购物车" >
          <template slot-scope="scope">
            <el-button
              @click="cartAdd(scope)"
              type="text"
              size="medium"><i class="el-icon-plus"></i></el-button>
            <span v-if="scope.row.num !== 0">{{scope.row.num}}</span>
            <el-button
              v-if="scope.row.num !== 0"
              @click="cartRemove(scope)"
              type="text"
              size="medium"><i class="el-icon-minus"></i></el-button>
          </template>
        </el-table-column>
      </template>
    </Table>
  </div>
</template>

<script>
  import Dialog from "./basic/Dialog";
  import Table from "./basic/Table";

  export default {
    name: "MainTable",
    components: {
      Dialog,
      Table
    },
    created() {
      let storage = window.localStorage
      // null时初始化本地数据库，[]时是删完东西方便测试，所以也恢复初始化
      if (storage.getItem(this.storageItemName) == null || storage.getItem(this.storageItemName) === '[]') {
        storage.setItem(this.storageItemName, JSON.stringify(this.tBody))
      }
      this.tBody = JSON.parse(storage.getItem(this.storageItemName))
    },
    data() {
      // 修改页面内容只需要修改data中的前三个属性，所有功能自动绑定
      return {
        // 本地数据库中存的数据的键名
        storageItemName: 'book',
        // 表头，可自定义，每一列的prop属性需要和tBody的属性名一致
        tHead: this.ttHead,
        // 如tHead中一列的表头是'书名'，其下的tBody数据属性名为bookName，那么tHead中这个对象的prop属性值为'bookName'
        tBody: this.ttBody,
        form: {

        },
        formLabelWidth: '120px',
        dialogType: 0,
      }
    },
    props: {
      ttHead: {
        default() {
          return [
            {
              label: '书名',
              prop: 'bookName'
            },
            {
              label: '作者',
              prop: 'author'
            },
            {
              label: '分类',
              prop: 'category'
            },
            {
              label: '价格',
              prop: 'price'
            }
          ]
        }
      },
      // 初始数据，可自定义
      ttBody: {
        default() {
          return []
        }
      },
      category: {
        default() {
          return '全部'
        }
      },
      search: {
        default() {
          return -1
        }
      },
      isAdmin: {
        default() {
          return false
        }
      }
    },
    computed: {
      bookDisplay() {
        if (this.search !== -1) {
          this.tBody[this.search].index = this.search
          return [this.tBody[this.search]]
        }
        let result = []
        let copyItem;
        this.tBody.forEach((item, index) => {
          if ('全部' === this.category || item.category === this.category) {
            copyItem = JSON.parse(JSON.stringify(item))
            copyItem['index'] = index
            result.push(copyItem)
          }
        })
        return result
      },
      bookValue() {
        let result = []
        this.bookDisplay.forEach((item, index) => {
          result.push({
            value: item.bookName + '（' + item.author + '）',
            index,
          })
        })
        return result
      },
      dialogTitle() {
        // 下面这种写法扩展性差，只能2选1
        // return this.dialogType === 0 ? '新增' : '编辑'
        if (0 === this.dialogType) {
          return '新增'
        } else if (1 === this.dialogType) {
          return '编辑'
        }
      },
      determineButtonName() {
        if (0 === this.dialogType) {
          return '增加'
        } else if (1 === this.dialogType) {
          return '更新'
        }
      }
    },
    watch: {
      tBody: {
        handler() {
          let copy = JSON.parse(JSON.stringify(this.tBody))
          copy.forEach((item,index)=>{
            item.num = 0
          })
          window.localStorage.setItem(this.storageItemName, JSON.stringify(copy))
          this.$emit('bookList', this.tBody)
        },
        // 对象需要深度监听
        deep: true
      },
      ttBody: {
        handler() {
          this.tBody = this.ttBody
        }
      },
      bookValue: {
        handler() {
          this.$emit('bookValueChange', this.bookValue)
        }
      }
    },
    methods: {
      rowDelete(index) {
        this.$refs.deleteConfirm.args = {
          index
        }
        this.$refs.deleteConfirm.dialogFormVisible = true
      },
      rowDeleted(args) {
        this.tBody.splice(args.index, 1)
      },
      rowUpdate(index) {
        this.dialogType = 1
        this.form = JSON.parse(JSON.stringify(this.tBody[index]))
        this.$refs.dialog.args = {
          index
        }
        this.$refs.dialog.dialogFormVisible = true
      },
      rowAdd() {
        this.dialogType = 0
        this.form = {}
        this.$refs.dialog.dialogFormVisible = true
      },
      determine(args) {
        if (1 === this.dialogType) {
          // 下面这种覆盖的方式会删除vue的监听，原因是 this.tBody[args.index] 的对象引用是一个新的json对象而不是vue之前监听的observer对象
          // this.tBody[args.index] = JSON.parse(JSON.stringify(this.form))
          this.tBody.splice(args.index, 1, JSON.parse(JSON.stringify(this.form)))
        } else if (0 === this.dialogType) {
          this.tBody.push(JSON.parse(JSON.stringify(this.form)))
          this.tBody[this.tBody.length -1].num = 0
        }
      },
      cartAdd(scope) {
        this.tBody[scope.row.index].num ++
      },
      cartRemove(scope) {
        this.tBody[scope.row.index].num --
      }
    }
  }
</script>

<style scoped>
  #main-table {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
</style>
